package com.jade.store.pay.service;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.jade.bss.DbException;
import com.jade.bss.base.customer.Customer;
import com.jade.bss.db.impl.BaseFacadeImpl;
import com.jade.framework.base.criterion.Criteria;
import com.jade.framework.base.criterion.Restrictions;
import com.jade.framework.base.util.PagingList;
import com.jade.store.pay.dao.PayOrderDao;
import com.jade.store.pay.dao.PayReturnOrderDao;
import com.jade.store.pay.dao.WithDrawDao;
import com.jade.store.pay.entity.PayOrder;
import com.jade.store.pay.entity.PayOrderDetail;
import com.jade.store.pay.entity.PayReturnOrder;
import com.jade.store.pay.entity.WithDraw;
import com.jade.store.pay.service.alipay.AlipayConfig;
import com.jade.store.pay.service.alipay.trade.config.Configs;
import com.jade.store.pay.service.alipay.trade.model.ExtendParams;
import com.jade.store.pay.service.alipay.trade.model.GoodsDetail;
import com.jade.store.pay.service.alipay.trade.model.builder.AlipayTradePayRequestBuilder;
import com.jade.store.pay.service.alipay.trade.model.builder.AlipayTradePrecreateRequestBuilder;
import com.jade.store.pay.service.alipay.trade.model.result.AlipayF2FPayResult;
import com.jade.store.pay.service.alipay.trade.model.result.AlipayF2FPrecreateResult;
import com.jade.store.pay.service.alipay.trade.service.AlipayTradeService;
import com.jade.store.pay.service.alipay.trade.service.impl.AlipayTradeServiceImpl;
import com.jade.store.pay.service.tencent.WXPay;
import com.jade.store.pay.service.tencent.protocol.pay_protocol.ScanPayReqData;
import com.jade.store.pay.service.tencent.protocol.pay_protocol.ScanPayResData;
import com.jade.store.pay.service.tencent.protocol.pay_query_protocol.ScanPayQueryReqData;
import com.jade.store.pay.service.tencent.protocol.pay_query_protocol.ScanPayQueryResData;
import com.jade.store.pay.service.tencent.protocol.pay_unifiedorder.PayUnifiedorderReqData;
import com.jade.store.pay.service.tencent.protocol.pay_unifiedorder.PayUnifiedorderResData;
import com.jade.store.pay.service.tencent.protocol.reverse_protocol.ReverseReqData;
import com.jade.store.pay.service.tencent.protocol.reverse_protocol.ReverseResData;
import com.jade.zsy.base.common.ConstantUtil;
import com.jade.zsy.base.common.EncodeImgZxing;
import com.jade.zsy.base.common.TimeString;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: JinYa 2009_jinya@163.coms
 * Date: 2016-11-10
 * Time: 19:05
 * Version : 1.0
 * Remark:
 * History:
 */
@Named("PayOrderFacade")
public class PayOrderFacadeImpl extends BaseFacadeImpl implements PayOrderFacade {
    private  static AlipayClient alipayClient=null;
    static {
        Configs.init("/jade/zsy/web/pss/config/alipay.properties");
        //调用RSA签名方式
        alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);
    }
    //密钥配置
    private static Auth auth = Auth.create(ConstantUtil.QINIU_AK, ConstantUtil.QINIU_SK);
    //创建上传对象
    private UploadManager uploadManager = new UploadManager();

    @Inject
    @Named("PayOrderDao")
    private PayOrderDao payOrderDao;
    @Inject
    @Named("WithDrawDao")
    private WithDrawDao withDrawDao;
    @Inject
    @Named("PayReturnOrderDao")
    private PayReturnOrderDao payReturnOrderDao;

    /**
     * JS微信公众号支付編碼
     * @param customer 请求用户
     * @param payOrder 请求订单
     * @return
     * @throws DbException
     */
    @Transactional(propagation= Propagation.REQUIRED)
    public PayOrder getWxJsPayCode(Customer customer, PayOrder payOrder) throws DbException {
        try{
            if(customer!=null){
                payOrder.setCode(customer.getName());
                payOrder.setPayNo(customer.getId() + (new TimeString().getTimeString()));
                payOrder.setCreator(customer.getName());
                payOrder.setCreatorId(customer.getId());
                payOrder.setEmployeeId(customer.getId());
                payOrder.setOwnerId(customer.getOwnerId());
            }
            payOrder.setType(PayOrder.TYPE_TENCENT_PULBIC);
            payOrder.setPayNo("W" + (new TimeString().getTimeString()));
            payOrder.setNotify_url(payOrder.getNotify_url());
            payOrder.setBody(payOrder.getStoreName() + "-向您收款");
            payOrder.setDetail(payOrder.getStoreName() + "向您收款");
            payOrder.setOut_trade_no("P" + System.currentTimeMillis() + (long) (Math.random() * 10000000L));
            PayUnifiedorderReqData req =new PayUnifiedorderReqData(payOrder.getBody(),payOrder.getDetail(),payOrder.getAttach(),payOrder.getOut_trade_no(),(int)(payOrder.getTotal_fee()*100),payOrder.getDevice_info(),payOrder.getSpbill_create_ip(),payOrder.getTime_start(),payOrder.getTime_expire(),payOrder.getGoods_tag(),payOrder.getNotify_url(),"JSAPI", payOrder.getOpenid());
            payOrder.setAppid(req.getAppid());
            payOrder.setSign(req.getSign());
            payOrder.setNonce_str(req.getNonce_str());
            payOrder.setTime_expire(req.getTime_expire());
            payOrder.setTimeStamp(System.currentTimeMillis());
            String  resResult=WXPay.requestPayUnifiedOrderService(req);
            PayUnifiedorderResData payRes=new PayUnifiedorderResData();
            payRes =payRes.getReturnXml(resResult);
            payOrder.setResult_code(payRes.getResult_code());
            payOrder.setErr_code(payRes.getErr_code());
            payOrder.setErr_code_des(payRes.getErr_code_des());
            payOrder.setTrade_type(payRes.getTrade_type());
            payOrder.setReturn_code(payRes.getReturn_code());
            payOrder.setReturn_msg(payRes.getReturn_msg());
            payOrder.setPrepay_id(payRes.getPrepay_id());
            payOrderDao.save(payOrder);
        }catch (Exception e){
            System.out.print(e.toString());
        }
        return payOrder;
    }
    /**
     * 微信扫码支付
     * @param customer 请求用户
     * @param payOrder 请求订单
     * @return
     * @throws DbException
     */
    @Transactional(propagation= Propagation.REQUIRED)
    public PayOrder getWxPayQRCode(Customer customer, PayOrder payOrder) throws DbException {
        try{
            payOrder.setType(PayOrder.TYPE_TENCENT);
            payOrder.setCode(customer.getName());
            payOrder.setPayNo(customer.getId() + (new TimeString().getTimeString()));
            payOrder.setNotify_url(payOrder.getNotify_url());
            payOrder.setCreator(customer.getName());
            payOrder.setCreatorId(customer.getId());
            payOrder.setEmployeeId(customer.getId());
            payOrder.setOwnerId(customer.getOwnerId());
            payOrder.setBody(payOrder.getStoreName() + "向您收款");
            payOrder.setOut_trade_no("p" + System.currentTimeMillis() + (long)(Math.random() * 10000000L));
            PayUnifiedorderReqData payUnifiedorderReqData =new PayUnifiedorderReqData(payOrder.getBody(),payOrder.getDetail(),payOrder.getAttach(),payOrder.getOut_trade_no(),(int)(payOrder.getTotal_fee()*100),payOrder.getDevice_info(),payOrder.getSpbill_create_ip(),payOrder.getTime_start(),payOrder.getTime_expire(),payOrder.getGoods_tag(),payOrder.getNotify_url());
            String  resResult=WXPay.requestPayUnifiedOrderService(payUnifiedorderReqData);
            PayUnifiedorderResData payRes=new PayUnifiedorderResData();
            payRes =payRes.getReturnXml(resResult);
            payOrder.setResult_code(payRes.getResult_code());
            payOrder.setErr_code(payRes.getErr_code());
            payOrder.setErr_code_des(payRes.getErr_code_des());
            payOrder.setPrepay_id(payRes.getPrepay_id());
            String fileName=payRes.getPrepay_id()+".jpg";
            File targetPath = new File(ConstantUtil.FILE_STORE_WX_PER_UPLOAD+File.separator+fileName);
            EncodeImgZxing.writeToFile(payRes.getCode_url(), "jpeg", targetPath);
            com.qiniu.http.Response res = uploadManager.put(targetPath.getPath(), targetPath.getName(), auth.uploadToken(ConstantUtil.QINIU_BUCKETNAME));
            payOrder.setCode_url(ConstantUtil.QINIU_VISTOR_URL + targetPath.getName());
            payOrder.setPrepay_id(payRes.getPrepay_id());
            payOrder.setTrade_type(payRes.getTrade_type());
            payOrder.setReturn_code(payRes.getReturn_code());
            payOrder.setReturn_msg(payRes.getReturn_msg());
            payOrderDao.save(payOrder);
        }catch (Exception e){
           System.out.print(e.toString());
        }
        return payOrder;
    }

    /**
     * 微信刷卡支付
     * @param customer
     * @param payOrder
     * @return
     * @throws DbException
     */
    @Transactional(propagation= Propagation.REQUIRED)
    public PayOrder getAppPay(Customer customer, PayOrder payOrder) throws DbException {
        try{
            payOrder.setType(PayOrder.TYPE_TENCENT_SCAN);
            payOrder.setCode(customer.getName());
            payOrder.setPayNo(customer.getId() + (new TimeString().getTimeString()));
            payOrder.setCreator(customer.getName());
            payOrder.setCreatorId(customer.getId());
            payOrder.setOwnerId(customer.getOwnerId());
            payOrder.setBody(payOrder.getStoreName() + "向您收款");
            payOrder.setOut_trade_no("p" + System.currentTimeMillis() + (long) (Math.random() * 10000000L));
            ScanPayReqData scanPayReqData =new ScanPayReqData(payOrder.getAuthCode(),payOrder.getDetail(),payOrder.getAttach(),payOrder.getOut_trade_no(),(int)(payOrder.getTotal_fee()*100),payOrder.getDevice_info(),payOrder.getSpbill_create_ip(),payOrder.getTime_start(),payOrder.getTime_expire(),payOrder.getGoods_tag());
            String scanResultStr=WXPay.requestScanPayService(scanPayReqData);
            ScanPayResData scanResult = new ScanPayResData();
            scanResult=scanResult.getByXml(scanResultStr);
            payOrder.setReturn_code(scanResult.getReturn_code());
            payOrder.setResult_code(scanResult.getReturn_code());
            payOrder.setReturn_msg(scanResult.getReturn_msg());
            payOrder.setErr_code(scanResult.getErr_code());
            payOrder.setErr_code_des(scanResult.getErr_code_des());
            payOrder.setOpenid(scanResult.getOpenid());
            payOrder.setAppid(scanResult.getAppid());
            payOrder.setIs_subscribe(scanResult.getIs_subscribe());
            payOrder.setTrade_type(scanResult.getTrade_type());
            payOrder.setBank_type(scanResult.getBank_type());
            payOrderDao.save(payOrder);
            if(payOrder.getReturn_code().equals("SUCCESS") && payOrder.getResult_code().equals("SUCCESS")){
                payOrder.setStatus(PayOrder.STATUS_SUC);
                WithDraw withDraw = new WithDraw();
                withDraw.setPayNo(payOrder.getPayNo());
                withDraw.setStatus(WithDraw.STATUS_NO);
                withDraw.setAmount(new BigDecimal(payOrder.getTotal_fee() / 100));
                if(payOrder.getBusType()==PayOrder.BUS_TYPE_GOODS){
                    withDraw.setTitle("商品收银");
                }
                else if(payOrder.getBusType()==PayOrder.BUS_TYPE_CRM_RECHARGE){
                    withDraw.setTitle("会员充值");
                }else {
                    withDraw.setTitle("其他收入");
                }
                withDraw.setCounterFee(new BigDecimal(payOrder.getTotal_fee() * 0.006));
                withDraw.setSettleFee(withDraw.getAmount().subtract(withDraw.getCounterFee()));
                withDraw.setOrderNo(payOrder.getOutTradeNo());
                withDraw.setPayType("微信");
                withDraw.setRemark(payOrder.getBody());
                withDraw.setEmployeeName(payOrder.getEmployeeName());
                withDraw.setEmployeeId(payOrder.getEmployeeId());
                withDraw.setStoreName(payOrder.getStoreName());
                withDraw.setStoreId(payOrder.getStoreId());
                withDraw.setCreator(payOrder.getCreator());
                withDraw.setCreatorId(payOrder.getCreatorId());
                withDraw.setOwnerId(payOrder.getOwnerId());
                withDrawDao.save(withDraw);
            }
        }catch (Exception e){
            System.out.print(e.toString());
        }
        return payOrder;
    }
    /**
     * 微信APP支付
     * @param customer
     * @param payOrder
     * @return
     * @throws DbException
     */
    @Transactional(propagation= Propagation.REQUIRED)
    public PayOrder wxAppPay(Customer customer, PayOrder payOrder) throws DbException{
        try{
            if(customer!=null){
                payOrder.setCode(customer.getName());
                payOrder.setPayNo(customer.getId() + (new TimeString().getTimeString()));
                payOrder.setCreator(customer.getName());
                payOrder.setCreatorId(customer.getId());
                payOrder.setEmployeeId(customer.getId());
                payOrder.setOwnerId(customer.getOwnerId());
            }
            payOrder.setType(PayOrder.TYPE_TENCENT_APP);
            payOrder.setPayNo("W" + (new TimeString().getTimeString()));
            payOrder.setNotify_url(payOrder.getNotify_url());
            payOrder.setBody(payOrder.getStoreName() + "-向您收款");
            payOrder.setDetail(payOrder.getStoreName() + "向您收款");
            payOrder.setOut_trade_no("P" + System.currentTimeMillis() + (long) (Math.random() * 10000000L));
            PayUnifiedorderReqData req =new PayUnifiedorderReqData(payOrder.getBody(),payOrder.getDetail(),payOrder.getAttach(),payOrder.getOut_trade_no(),(int)(payOrder.getTotal_fee()*100),payOrder.getDevice_info(),payOrder.getSpbill_create_ip(),payOrder.getTime_start(),payOrder.getTime_expire(),payOrder.getGoods_tag(),payOrder.getNotify_url(),"APP", payOrder.getOpenid());
            payOrder.setAppid(req.getAppid());
            payOrder.setSign(req.getSign());
            payOrder.setNonce_str(req.getNonce_str());
            payOrder.setTime_expire(req.getTime_expire());
            payOrder.setTimeStamp(System.currentTimeMillis());
            String  resResult=WXPay.requestPayUnifiedOrderService(req);
            PayUnifiedorderResData payRes=new PayUnifiedorderResData();
            payRes =payRes.getReturnXml(resResult);
            payOrder.setResult_code(payRes.getResult_code());
            payOrder.setErr_code(payRes.getErr_code());
            payOrder.setErr_code_des(payRes.getErr_code_des());
            payOrder.setTrade_type(payRes.getTrade_type());
            payOrder.setReturn_code(payRes.getReturn_code());
            payOrder.setReturn_msg(payRes.getReturn_msg());
            payOrder.setPrepay_id(payRes.getPrepay_id());
            payOrderDao.save(payOrder);
        }catch (Exception e){
            System.out.print(e.toString());
        }
        return payOrder;
    }
    /**
     * 微信刷卡支付
     * @param customer
     * @param payOrder
     * @return
     * @throws DbException
     */
    @Transactional(propagation= Propagation.REQUIRED)
    public PayOrder getWxScanPay(final Customer customer, final PayOrder payOrder) throws DbException {
        try{
            payOrder.setType(PayOrder.TYPE_TENCENT_SCAN);
            payOrder.setCode(customer.getName());
            payOrder.setPayNo(customer.getId() + (new TimeString().getTimeString()));
            payOrder.setCreator(customer.getName());
            payOrder.setCreatorId(customer.getId());
            payOrder.setOwnerId(customer.getOwnerId());
            payOrder.setBody(payOrder.getStoreName() + "向您收款");
            payOrder.setTotalAmount(String.valueOf(payOrder.getTotal_fee()));
            payOrder.setStatus(PayOrder.STATUS_INIT);
            payOrder.setOut_trade_no("p" + System.currentTimeMillis() + (long) (Math.random() * 10000000L));
            ScanPayReqData scanPayReqData =new ScanPayReqData(payOrder.getAuthCode(),payOrder.getDetail(),payOrder.getAttach(),payOrder.getOut_trade_no(),(int)(payOrder.getTotal_fee()*100),payOrder.getDevice_info(),payOrder.getSpbill_create_ip(),payOrder.getTime_start(),payOrder.getTime_expire(),payOrder.getGoods_tag());
            String scanResultStr=WXPay.requestScanPayService(scanPayReqData);
            ScanPayResData scanResult = new ScanPayResData();
            scanResult=scanResult.getByXml(scanResultStr);
            payOrder.setReturn_code(scanResult.getReturn_code());
            payOrder.setResult_code(scanResult.getReturn_code());
            payOrder.setReturn_msg(scanResult.getReturn_msg());
            payOrder.setErr_code(scanResult.getErr_code());
            payOrder.setErr_code_des(scanResult.getErr_code_des());
            payOrder.setOpenid(scanResult.getOpenid());
            payOrder.setAppid(scanResult.getAppid());
            payOrder.setIs_subscribe(scanResult.getIs_subscribe());
            payOrder.setTrade_type(scanResult.getTrade_type());
            payOrder.setBank_type(scanResult.getBank_type());
            if(payOrder.getReturn_code().equals("SUCCESS") && payOrder.getResult_code().equals("SUCCESS")){
                if(org.apache.commons.lang3.StringUtils.isEmpty(payOrder.getErr_code())){//免密支付成功
                    payOrder.setStatus(PayOrder.STATUS_SUC);
                    WithDraw withDraw = new WithDraw();
                    withDraw.setPayNo(payOrder.getPayNo());
                    withDraw.setStatus(WithDraw.STATUS_NO);
                    withDraw.setAmount(new BigDecimal(payOrder.getTotal_fee()));
                    if(payOrder.getBusType()==PayOrder.BUS_TYPE_GOODS){
                        withDraw.setTitle("商品收银");
                    }
                    else if(payOrder.getBusType()==PayOrder.BUS_TYPE_CRM_RECHARGE){
                        withDraw.setTitle("会员充值");
                    }else {
                        withDraw.setTitle("其他收入");
                    }
                    withDraw.setCounterFee(new BigDecimal(payOrder.getTotal_fee() * 0.006));
                    withDraw.setSettleFee(withDraw.getAmount().subtract(withDraw.getCounterFee()));
                    withDraw.setOrderNo(payOrder.getOutTradeNo());
                    withDraw.setPayType("微信");
                    withDraw.setRemark(payOrder.getBody());
                    withDraw.setEmployeeName(payOrder.getEmployeeName());
                    withDraw.setEmployeeId(payOrder.getEmployeeId());
                    withDraw.setStoreName(payOrder.getStoreName());
                    withDraw.setStoreId(payOrder.getStoreId());
                    withDraw.setRemark(payOrder.getBody());
                    withDraw.setCreator(payOrder.getCreator());
                    withDraw.setCreatorId(payOrder.getCreatorId());
                    withDraw.setOwnerId(payOrder.getOwnerId());
                    withDrawDao.save(withDraw);
                }else if(payOrder.getErr_code().equals("USERPAYING")){//需要用户加密查询
                    payOrder.setStatus(PayOrder.STATUS_PS);
                } else if(payOrder.getErr_code().equals("AUTH_CODE_INVALID")){//需要用户加密查询
                    payOrder.setStatus(PayOrder.STATUS_FAI);
                }
            }
            payOrderDao.save(payOrder);
        }catch (Exception e){
            System.out.print(e.toString());
        }
        return payOrder;
    }
    /**
     *支付宝手机网站支付
     * @param customer
     * @param payOrder
     * @return
     * @throws DbException
     */
    @Transactional(propagation= Propagation.REQUIRED)
    public PayOrder getAliPayWap(Customer customer, PayOrder payOrder) throws DbException {
        try{
            payOrder.setType(PayOrder.TYPE_ALIPAY_WAP);
            payOrder.setCode(customer.getName());
            payOrder.setPayNo(customer.getId() + (new TimeString().getTimeString()));
            payOrder.setNotify_url(payOrder.getNotify_url());
            payOrder.setCreator(customer.getName());
            payOrder.setCreatorId(customer.getId());
            payOrder.setOwnerId(customer.getOwnerId());
            payOrder.setBody(payOrder.getStoreName() + "向您收款");
            payOrder.setOut_trade_no("p" + System.currentTimeMillis() + (long)(Math.random() * 10000000L));

            AlipayTradeWapPayRequest alipayTradeService= new AlipayTradeWapPayRequest();
// (必填) 商户网站订单系统中唯一订单号，64个字符以内，只能包含字母、数字、下划线，
            // (必填) 订单标题，粗略描述用户的支付目的。如“xxx品牌xxx门店当面付扫码消费”
            String subject = payOrder.getBody();
            // (必填) 订单总金额，单位为元，不能超过1亿元
            // 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
            String totalAmount = String.valueOf(payOrder.getTotal_fee());
            // (可选) 订单不可打折金额，可以配合商家平台配置折扣活动，如果酒水不参与打折，则将对应金额填写至此字段
            // 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
            String undiscountableAmount = "0";
            // 卖家支付宝账号ID，用于支持一个签约账号下支持打款到不同的收款账号，(打款到sellerId对应的支付宝账号)
            // 如果该字段为空，则默认为与支付宝签约的商户的PID，也就是appid对应的PID
            String sellerId = "";
            // 订单描述，可以对交易或商品进行一个详细地描述，比如填写"购买商品2件共15.00元"
            String body = payOrder.getDetail();
            // 商户操作员编号，添加此参数可以为商户操作员做销售统计
            String operatorId = String.valueOf(customer.getId());

            // (必填) 商户门店编号，通过门店号和商家后台可以配置精准到门店的折扣信息，详询支付宝技术支持

            // 业务扩展参数，目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法)，详情请咨询支付宝技术支持
            ExtendParams extendParams = new ExtendParams();
            extendParams.setSysServiceProviderId("2088611770536026");
            // 支付超时，定义为120分钟
            String timeoutExpress = "120m";
            // 商品明细列表，需填写购买商品详细信息，
            List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>();
            if(payOrder.getDetailList()!=null && payOrder.getDetailList().size()>0){
                for(PayOrderDetail payOrderDetail : payOrder.getDetailList()){
                    GoodsDetail goods1 = GoodsDetail.newInstance(payOrderDetail.getGoodsId(), payOrderDetail.getGoodsName(), payOrderDetail.getPrice(), payOrderDetail.getQuantity());
                    // 创建好一个商品后添加至商品明细列表
                    goodsDetailList.add(goods1);
                }
            }
            // 创建扫码支付请求builder，设置请求参数
            AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
                    .setSubject(subject)
                    .setTotalAmount(totalAmount)
                    .setOutTradeNo(payOrder.getOut_trade_no())
                    .setUndiscountableAmount(undiscountableAmount)
                    .setSellerId(sellerId)
                    .setBody(body)
                    .setOperatorId(operatorId)
                    .setStoreId("0")
                    .setExtendParams(extendParams)
                    .setTimeoutExpress(timeoutExpress)
                    .setNotifyUrl(payOrder.getNotify_url())//支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置
                    .setGoodsDetailList(goodsDetailList);
            payOrderDao.save(payOrder);

        }catch (Exception e){
            System.out.print(e.toString());
        }
        return payOrder;
    }

    /**
     *支付宝二维码安置费
     * @param customer
     * @param payOrder
     * @return
     * @throws DbException
     */
    @Transactional(propagation= Propagation.REQUIRED)
    public PayOrder getAliPayQRCode(Customer customer, PayOrder payOrder) throws DbException {
        try{
            payOrder.setType(PayOrder.TYPE_ALIPAY);
            payOrder.setCode(customer.getName());
            payOrder.setPayNo(customer.getId() + (new TimeString().getTimeString()));
            payOrder.setNotify_url(payOrder.getNotify_url());
            payOrder.setCreator(customer.getName());
            payOrder.setCreatorId(customer.getId());
            payOrder.setOwnerId(customer.getOwnerId());
            payOrder.setBody(payOrder.getStoreName() + "向您收款");
            payOrder.setOut_trade_no("p" + System.currentTimeMillis() + (long) (Math.random() * 10000000L));
            AlipayTradeService alipayTradeService= new AlipayTradeServiceImpl.ClientBuilder().build();
// (必填) 商户网站订单系统中唯一订单号，64个字符以内，只能包含字母、数字、下划线，
            // (必填) 订单标题，粗略描述用户的支付目的。如“xxx品牌xxx门店当面付扫码消费”
            String subject = payOrder.getBody();
            // (必填) 订单总金额，单位为元，不能超过1亿元
            // 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
            String totalAmount = String.valueOf(payOrder.getTotal_fee());
            // (可选) 订单不可打折金额，可以配合商家平台配置折扣活动，如果酒水不参与打折，则将对应金额填写至此字段
            // 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
            String undiscountableAmount = "0";
            // 卖家支付宝账号ID，用于支持一个签约账号下支持打款到不同的收款账号，(打款到sellerId对应的支付宝账号)
            // 如果该字段为空，则默认为与支付宝签约的商户的PID，也就是appid对应的PID
            String sellerId = "";
            // 订单描述，可以对交易或商品进行一个详细地描述，比如填写"购买商品2件共15.00元"
            String body = payOrder.getDetail();
            // 商户操作员编号，添加此参数可以为商户操作员做销售统计
            String operatorId = String.valueOf(customer.getId());

            // (必填) 商户门店编号，通过门店号和商家后台可以配置精准到门店的折扣信息，详询支付宝技术支持
            String storeId = String.valueOf(0);
            // 业务扩展参数，目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法)，详情请咨询支付宝技术支持
            ExtendParams extendParams = new ExtendParams();
            extendParams.setSysServiceProviderId("2088611770536026");
            // 支付超时，定义为120分钟
            String timeoutExpress = "120m";
            // 商品明细列表，需填写购买商品详细信息，
            List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>();
            if(payOrder.getDetailList()!=null && payOrder.getDetailList().size()>0){
                for(PayOrderDetail payOrderDetail : payOrder.getDetailList()){
                    GoodsDetail goods1 = GoodsDetail.newInstance(payOrderDetail.getGoodsId(), payOrderDetail.getGoodsName(), payOrderDetail.getPrice(), payOrderDetail.getQuantity());
                    // 创建好一个商品后添加至商品明细列表
                    goodsDetailList.add(goods1);
                }
            }
            // 创建扫码支付请求builder，设置请求参数
            AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
                    .setSubject(subject)
                    .setTotalAmount(totalAmount)
                    .setOutTradeNo(payOrder.getOut_trade_no())
                    .setUndiscountableAmount(undiscountableAmount)
                    .setSellerId(sellerId)
                    .setBody(body)
                    .setOperatorId(operatorId)
                    .setStoreId(storeId)
                    .setExtendParams(extendParams)
                    .setTimeoutExpress(timeoutExpress)
                    .setNotifyUrl(payOrder.getNotify_url())//支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置
                    .setGoodsDetailList(goodsDetailList);

            AlipayF2FPrecreateResult results = alipayTradeService.tradePrecreate(builder);
            switch (results.getTradeStatus()) {
                case SUCCESS:
                    String fileName=payOrder.getPayNo()+".jpg";
                    File targetPath = new File(ConstantUtil.FILE_STORE_WX_PER_UPLOAD+File.separator+fileName);
                    EncodeImgZxing.writeToFile(results.getResponse().getQrCode(), "jpeg", targetPath);
                    com.qiniu.http.Response res = uploadManager.put(targetPath.getPath(), targetPath.getName(), auth.uploadToken(ConstantUtil.QINIU_BUCKETNAME));
                    payOrder.setCode_url(ConstantUtil.QINIU_VISTOR_URL + targetPath.getName());
                    break;
                case FAILED:

                    break;

                case UNKNOWN:

                    break;

                default:

                    break;
            }
            payOrderDao.save(payOrder);

        }catch (Exception e){
            System.out.print(e.toString());
        }
        return payOrder;
    }

    /**
     * 支付宝扫码支付
     * @param customer
     * @param payOrder
     * @return
     * @throws DbException
     */
    @Transactional(propagation= Propagation.REQUIRED)
    public PayOrder getAliScanPay(Customer customer, PayOrder payOrder) throws DbException {
        try{
            payOrder.setType(PayOrder.TYPE_ALIPAY_SCAN);
            payOrder.setCode(customer.getName());
            payOrder.setPayNo(customer.getId() + (new TimeString().getTimeString()));
            payOrder.setCreator(customer.getName());
            payOrder.setCreatorId(customer.getId());
            payOrder.setOwnerId(customer.getOwnerId());
            payOrder.setBody(payOrder.getStoreName() + "向您收款");
            payOrder.setOut_trade_no("p" + System.currentTimeMillis() + (long) (Math.random() * 10000000L));
            payOrder.setTotalAmount(String.valueOf(payOrder.getTotal_fee()));
            AlipayTradeService service= new AlipayTradeServiceImpl.ClientBuilder().build();
            // (必填) 订单标题，粗略描述用户的支付目的。如“xxx品牌xxx门店消费”
            String subject = payOrder.getBody();

            // (必填) 订单总金额，单位为元，不能超过1亿元
            // 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
            String totalAmount = String.valueOf(payOrder.getTotal_fee());

            // (必填) 付款条码，用户支付宝钱包手机app点击“付款”产生的付款条码
            String authCode =payOrder.getAuthCode(); // 条码示例，286648048691290423

            // (可选，根据需要决定是否使用) 订单可打折金额，可以配合商家平台配置折扣活动，如果订单部分商品参与打折，可以将部分商品总价填写至此字段，默认全部商品可打折
            // 如果该值未传入,但传入了【订单总金额】,【不可打折金额】 则该值默认为【订单总金额】- 【不可打折金额】
//        String discountableAmount = "1.00"; //

            // (可选) 订单不可打折金额，可以配合商家平台配置折扣活动，如果酒水不参与打折，则将对应金额填写至此字段
            // 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
            String undiscountableAmount = "0.0";

            // 卖家支付宝账号ID，用于支持一个签约账号下支持打款到不同的收款账号，(打款到sellerId对应的支付宝账号)
            // 如果该字段为空，则默认为与支付宝签约的商户的PID，也就是appid对应的PID
            String sellerId = "";

            // 订单描述，可以对交易或商品进行一个详细地描述，比如填写"购买商品3件共20.00元"
            String body = payOrder.getDetail();

            // 商户操作员编号，添加此参数可以为商户操作员做销售统计
            String operatorId = customer.getTrueName();

            // (必填) 商户门店编号，通过门店号和商家后台可以配置精准到门店的折扣信息，详询支付宝技术支持
            String storeId = String.valueOf(0);

            // 业务扩展参数，目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法)，详情请咨询支付宝技术支持
            String providerId = "2088611770536026";
            ExtendParams extendParams = new ExtendParams();
            extendParams.setSysServiceProviderId(providerId);
            // 支付超时，线下扫码交易定义为5分钟
            String timeoutExpress = "5m";

            // 商品明细列表，需填写购买商品详细信息，
            List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>();
            if(payOrder.getDetailList()!=null && payOrder.getDetailList().size()>0){
                for(PayOrderDetail payOrderDetail : payOrder.getDetailList()){
                    GoodsDetail goods1 = GoodsDetail.newInstance(payOrderDetail.getGoodsId(), payOrderDetail.getGoodsName(), payOrderDetail.getPrice(), payOrderDetail.getQuantity());
                    // 创建好一个商品后添加至商品明细列表
                    goodsDetailList.add(goods1);
                }
            }
             // String appAuthToken = "应用授权令牌";//根据真实值填写
            // 创建条码支付请求builder，设置请求参数
            AlipayTradePayRequestBuilder builder = new AlipayTradePayRequestBuilder()
                    //   .setAppAuthToken(appAuthToken)
                    .setOutTradeNo(payOrder.getOut_trade_no())
                    .setSubject(payOrder.getBody())
                    .setAuthCode(authCode)
                    .setTotalAmount(totalAmount)
                    .setStoreId(storeId)
                    .setUndiscountableAmount(undiscountableAmount)
                    .setBody(body)
                    .setOperatorId(operatorId)
                    .setExtendParams(extendParams)
                    .setSellerId(sellerId)
                    .setGoodsDetailList(goodsDetailList)
                    .setTimeoutExpress(timeoutExpress);

            // 调用tradePay方法获取当面付应答
            AlipayF2FPayResult alipayScanResult = service.tradePay(builder);
            switch (alipayScanResult.getTradeStatus()) {
                case SUCCESS:
                    payOrder.setReturn_code("SUCCESS");
                    payOrder.setResult_code("SUCCESS");
                    payOrder.setStatus(PayOrder.STATUS_SUC);
                    WithDraw withDraw=new WithDraw();
                    withDraw.setPayNo(payOrder.getPayNo());
                    withDraw.setStatus(WithDraw.STATUS_NO);
                    withDraw.setAmount(new BigDecimal(payOrder.getTotal_fee()));
                    if(payOrder.getBusType()==PayOrder.BUS_TYPE_GOODS){
                        withDraw.setTitle("商品收银");
                    }
                    else if(payOrder.getBusType()==PayOrder.BUS_TYPE_CRM_RECHARGE){
                        withDraw.setTitle("会员充值");
                    }else {
                        withDraw.setTitle("其他收入");
                    }
                    withDraw.setCounterFee(new BigDecimal(payOrder.getTotal_fee() * 0.006));
                    withDraw.setSettleFee(withDraw.getAmount().subtract(withDraw.getCounterFee()));
                    withDraw.setOrderNo(payOrder.getOutTradeNo());
                    withDraw.setRemark(payOrder.getBody());
                    withDraw.setEmployeeName(payOrder.getEmployeeName());
                    withDraw.setEmployeeId(payOrder.getEmployeeId());
                    withDraw.setStoreName(payOrder.getStoreName());
                    withDraw.setStoreId(payOrder.getStoreId());
                    withDraw.setPayType("支付宝");
                    withDraw.setRemark(payOrder.getBody());
                    withDraw.setCreator(payOrder.getCreator());
                    withDraw.setCreatorId(payOrder.getCreatorId());
                    withDraw.setOwnerId(payOrder.getOwnerId());
                    withDrawDao.save(withDraw);
                    break;

                case FAILED:
                    payOrder.setStatus(PayOrder.STATUS_FAI);
                    break;

                case UNKNOWN:
                    break;
                default:

                    break;
            }
            payOrderDao.save(payOrder);

        }catch (Exception e){
            System.out.print(e.toString());
        }
        return payOrder;
    }

    /**
     * 微信支付返回結果
     * @param request
     * @return
     * @throws DbException
     */
    @Transactional(propagation= Propagation.REQUIRED)
    public PayReturnOrder getWxPayReturn(HttpServletRequest request) throws DbException{
        PayReturnOrder returnOrder=new PayReturnOrder();
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
            StringBuffer sb = new StringBuffer();
            String line = null;
            while ((line=br.readLine()) != null) {
                sb = sb.append(line);
            }
            String postData = sb.toString();
            returnOrder=returnOrder.getWxRereturn(postData);
            payReturnOrderDao.save(returnOrder);
        }catch (Exception e){}
        return returnOrder;
    }

    /**
     * 阿里 手机网站支付
     * @param customer
     * @param payOrder
     * @return
     * @throws DbException
     */
    @Transactional(propagation= Propagation.REQUIRED)
    public PayOrder aliWapPay(Customer customer, PayOrder payOrder,HttpServletResponse response) throws DbException {
        try{
            if(customer!=null){
                payOrder.setCode(customer.getName());
                payOrder.setPayNo(customer.getId() + (new TimeString().getTimeString()));
                payOrder.setCreator(customer.getName());
                payOrder.setCreatorId(customer.getId());
                payOrder.setEmployeeId(customer.getId());
                payOrder.setOwnerId(customer.getOwnerId());
            }
            payOrder.setType(PayOrder.TYPE_ALIPAY);
            payOrder.setPayNo("W" + (new TimeString().getTimeString()));
            payOrder.setTotalAmount(payOrder.getTotalAmount()); 
            payOrder.setNotify_url(payOrder.getNotify_url());
            payOrder.setBody(payOrder.getStoreName() + "-向您收款");
            payOrder.setDetail(payOrder.getStoreName() + "向您收款");
            payOrder.setOut_trade_no("P" + System.currentTimeMillis() + (long) (Math.random() * 10000000L));
            String subject = payOrder.getBody();
            // (必填) 订单总金额，单位为元，不能超过1亿元
            // 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
            String totalAmount = String.valueOf(payOrder.getTotal_fee());
            // (可选，根据需要决定是否使用) 订单可打折金额，可以配合商家平台配置折扣活动，如果订单部分商品参与打折，可以将部分商品总价填写至此字段，默认全部商品可打折
            // 如果该值未传入,但传入了【订单总金额】,【不可打折金额】 则该值默认为【订单总金额】- 【不可打折金额】
//        String discountableAmount = "1.00"; //
            // (可选) 订单不可打折金额，可以配合商家平台配置折扣活动，如果酒水不参与打折，则将对应金额填写至此字段
            // 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
            String undiscountableAmount = "0.0";
            // 商户操作员编号，添加此参数可以为商户操作员做销售统计

            // 业务扩展参数，目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法)，详情请咨询支付宝技术支持
            String providerId = "2088611770536026";
            ExtendParams extendParams = new ExtendParams();
            extendParams.setSysServiceProviderId(providerId);
            // 支付超时，线下扫码交易定义为5分钟
            String timeoutExpress = "5m";

            //调用RSA签名方式
            AlipayTradeWapPayRequest alipay_request=new AlipayTradeWapPayRequest();

            // 封装请求支付信息
            AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();
            model.setOutTradeNo(payOrder.getOut_trade_no());
            model.setSubject(payOrder.getBody());// (必填) 订单标题，粗略描述用户的支付目的。如“xxx品牌xxx门店消费”
            model.setTotalAmount(payOrder.getTotalAmount());
            model.setBody(payOrder.getDetail());  // 订单描述，可以对交易或商品进行一个详细地描述，比如填写"购买商品3件共20.00元"
            model.setTimeoutExpress(payOrder.getTime_expire());
            model.setProductCode(payOrder.getProduct_id());

            alipay_request.setBizModel(model);
            // 设置异步通知地址
            alipay_request.setNotifyUrl(payOrder.getNotify_url());
            // 设置同步地址
            alipay_request.setReturnUrl(payOrder.getCode_url());
            AlipayTradeWapPayResponse alipayTradeWapPayResponse=new AlipayTradeWapPayResponse();
            // form表单生产
            String form = "";
            try {
                // 调用SDK生成表单
                form = alipayClient.pageExecute(alipay_request).getBody();
                response.setContentType("text/html;charset=" + AlipayConfig.CHARSET);
                response.getWriter().write(form);//直接将完整的表单html输出到页面
                response.getWriter().flush();
                response.getWriter().close();
            } catch (AlipayApiException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            payOrderDao.save(payOrder);
        }catch (Exception e){
            System.out.print(e.toString());
        }
        return payOrder;
    }

    /**
     * 支付成功
     * @param customer
     * @param payOrder
     * @return
     * @throws Exception
     */
    @Transactional(propagation= Propagation.REQUIRED)
    public PayOrder successPay(Customer customer, PayOrder updateOrder)throws DbException{
        PayOrder payOrder=payOrderDao.getById(PayOrder.class,updateOrder.getId());
        if(payOrder==null || payOrder.getId()<=0)return payOrder;
        if(payOrder.getStatus()==PayOrder.STATUS_SUC)return payOrder;
        payOrder.setStatus(PayOrder.STATUS_SUC);
        WithDraw withDraw=new WithDraw();
        withDraw.setPayNo(payOrder.getPayNo());
        withDraw.setStatus(WithDraw.STATUS_NO);
        withDraw.setAmount(new BigDecimal(payOrder.getTotal_fee()));
        if(payOrder.getBusType()==PayOrder.BUS_TYPE_GOODS){
            withDraw.setTitle("商品收银");
        }
        else if(payOrder.getBusType()==PayOrder.BUS_TYPE_CRM_RECHARGE){
            withDraw.setTitle("会员充值");
        }else if(payOrder.getBusType()==PayOrder.BUS_TYPE_STORER){
            withDraw.setTitle("店铺收银");
        }else if(payOrder.getBusType()==PayOrder.BUS_TYPE_EMPLOYEE){
            withDraw.setTitle("导购收银");
        }else {
            withDraw.setTitle("其他收入");
        }
        withDraw.setCounterFee(new BigDecimal(payOrder.getTotal_fee() * 0.006));
        withDraw.setSettleFee(withDraw.getAmount().subtract(withDraw.getCounterFee()));
        withDraw.setOrderNo(payOrder.getOutTradeNo());
        withDraw.setRemark(payOrder.getBody());
        withDraw.setEmployeeName(payOrder.getEmployeeName());
        withDraw.setEmployeeId(payOrder.getEmployeeId());
        withDraw.setStoreName(payOrder.getStoreName());
        withDraw.setStoreId(payOrder.getStoreId());
        withDraw.setPayType("微信");
        withDraw.setRemark(payOrder.getBody());
        withDraw.setCreator(payOrder.getCreator());
        withDraw.setCreatorId(payOrder.getCreatorId());
        withDraw.setOwnerId(payOrder.getOwnerId());
        withDrawDao.save(withDraw);
        return payOrder;
    }

    /**
     * 支付成功
     * @param
     * @param payOrder
     * @return
     * @throws Exception
     */
    @Transactional(propagation= Propagation.REQUIRED)
    public PayOrder getReturnOrder(PayOrder payOrder)throws DbException {
        ScanPayQueryReqData scanPayQueryReqData=new ScanPayQueryReqData("",payOrder.getOut_trade_no());
        try{
            String scanPayQueryResDataStr=WXPay.requestScanPayQueryService(scanPayQueryReqData);
            ScanPayQueryResData scanPayQueryResData = new ScanPayQueryResData();
            scanPayQueryResData=scanPayQueryResData.getByXml(scanPayQueryResDataStr);
            if(scanPayQueryResData.getTrade_state().equals("SUCCESS")){
                if(payOrder.getStatus()==PayOrder.STATUS_SUC)return payOrder;
                payOrder.setStatus(PayOrder.STATUS_SUC);
                payOrderDao.update(payOrder);
                WithDraw withDraw=new WithDraw();
                withDraw.setPayNo(payOrder.getPayNo());
                withDraw.setStatus(WithDraw.STATUS_NO);
                withDraw.setAmount(new BigDecimal(payOrder.getTotal_fee()));
                if(payOrder.getBusType()==PayOrder.BUS_TYPE_GOODS){
                    withDraw.setTitle("商品收银");
                }
                else if(payOrder.getBusType()==PayOrder.BUS_TYPE_CRM_RECHARGE){
                    withDraw.setTitle("会员充值");
                }else if(payOrder.getBusType()==PayOrder.BUS_TYPE_STORER){
                    withDraw.setTitle("店铺收银");
                }else if(payOrder.getBusType()==PayOrder.BUS_TYPE_EMPLOYEE){
                    withDraw.setTitle("导购收银");
                }else {
                    withDraw.setTitle("其他收入");
                }
                withDraw.setCounterFee(new BigDecimal(payOrder.getTotal_fee() * 0.006));
                withDraw.setSettleFee(withDraw.getAmount().subtract(withDraw.getCounterFee()));
                withDraw.setOrderNo(payOrder.getOutTradeNo());
                withDraw.setRemark(payOrder.getBody());
                withDraw.setEmployeeName(payOrder.getEmployeeName());
                withDraw.setEmployeeId(payOrder.getEmployeeId());
                withDraw.setStoreName(payOrder.getStoreName());
                withDraw.setStoreId(payOrder.getStoreId());
                withDraw.setPayType("微信");
                withDraw.setRemark(payOrder.getBody());
                withDraw.setCreator(payOrder.getCreator());
                withDraw.setCreatorId(payOrder.getCreatorId());
                withDraw.setOwnerId(payOrder.getOwnerId());
                withDrawDao.save(withDraw);
            }
        }catch (Exception e){
            System.out.print(e.toString());
        }
        return payOrder;
    }
    /**
     * 支付成功
     * @param customer
     * @param payOrder
     * @return
     * @throws Exception
     */
    @Transactional(propagation= Propagation.REQUIRED)
    public PayOrder cancelOrder(PayOrder payOrder)throws DbException{
        ReverseReqData scanPayQueryReqData=new ReverseReqData("",payOrder.getOut_trade_no());
        try{
            String scanPayQueryResDataStr=WXPay.requestReverseService(scanPayQueryReqData);
            ReverseResData reverseResData = new ReverseResData();
            reverseResData=reverseResData.getByXml(scanPayQueryResDataStr);
            if(reverseResData.getResult_code().equals("SUCCESS") && reverseResData.getReturn_code().equals("SUCCESS")){
                payOrder.setStatus(PayOrder.STATUS_FAI);
                if(payOrder.getStatus()==PayOrder.STATUS_FAI)return payOrder;
                payOrder.setStatus(PayOrder.STATUS_FAI);
                payOrder.setBody("交易失败" + payOrder.getBody());
                payOrderDao.update(payOrder);
            }
        }catch (Exception e){
            System.out.print(e.toString());
        }
        return payOrder;
    }

    @Transactional(propagation= Propagation.REQUIRED)
    public PayOrder getReturnOrder(Customer customer,String outTradeNo)throws DbException{
        PayOrder payOrder=this.getPayOrder(customer,outTradeNo);
        if(payOrder==null) return null;
        switch (payOrder.getType()){
            case PayOrder.TYPE_TENCENT:
            case PayOrder.TYPE_TENCENT_SCAN:
            case PayOrder.TYPE_TENCENT_APP:
            case PayOrder.TYPE_TENCENT_PULBIC:
                ScanPayQueryReqData scanPayQueryReqData=new ScanPayQueryReqData("",outTradeNo);
                try{
                    String scanPayQueryResDataStr=WXPay.requestScanPayQueryService(scanPayQueryReqData);
                    ScanPayQueryResData scanPayQueryResData = new ScanPayQueryResData();
                    scanPayQueryResData=scanPayQueryResData.getByXml(scanPayQueryResDataStr);
                    if(scanPayQueryResData.getTrade_state().equals("SUCCESS")){
                        if(payOrder.getStatus()==PayOrder.STATUS_SUC)return payOrder;
                        payOrder.setStatus(PayOrder.STATUS_SUC);
                        payOrderDao.update(payOrder);
                        WithDraw oldWithDraw=this.getWithDraw(customer,payOrder.getPayNo());
                        if(oldWithDraw==null || oldWithDraw.getId()<=0){
                            WithDraw withDraw=new WithDraw();
                            withDraw.setPayNo(payOrder.getPayNo());
                            withDraw.setStatus(WithDraw.STATUS_NO);
                            withDraw.setAmount(new BigDecimal(payOrder.getTotal_fee()));
                            if(payOrder.getBusType()==PayOrder.BUS_TYPE_GOODS){
                                withDraw.setTitle("商品收银");
                            }
                            else if(payOrder.getBusType()==PayOrder.BUS_TYPE_CRM_RECHARGE){
                                withDraw.setTitle("会员充值");
                            }else if(payOrder.getBusType()==PayOrder.BUS_TYPE_STORER){
                                withDraw.setTitle("店铺收银");
                            }else if(payOrder.getBusType()==PayOrder.BUS_TYPE_EMPLOYEE){
                                withDraw.setTitle("导购收银");
                            }else {
                                withDraw.setTitle("其他收入");
                            }
                            withDraw.setCounterFee(new BigDecimal(payOrder.getTotal_fee() * 0.006));
                            withDraw.setSettleFee(withDraw.getAmount().subtract(withDraw.getCounterFee()));
                            withDraw.setOrderNo(payOrder.getOutTradeNo());
                            withDraw.setRemark(payOrder.getBody());
                            withDraw.setEmployeeName(payOrder.getEmployeeName());
                            withDraw.setEmployeeId(payOrder.getEmployeeId());
                            withDraw.setStoreName(payOrder.getStoreName());
                            withDraw.setStoreId(payOrder.getStoreId());
                            withDraw.setPayType("微信");
                            withDraw.setRemark(payOrder.getBody());
                            withDraw.setCreator(payOrder.getCreator());
                            withDraw.setCreatorId(payOrder.getCreatorId());
                            withDraw.setOwnerId(payOrder.getOwnerId());
                            withDrawDao.save(withDraw);
                        }
                    }
                }catch (Exception e){
                    System.out.print(e.toString());
                }
                break;
        }
        return payOrder;
    }

    @Transactional(propagation= Propagation.REQUIRED)
    public PayOrder cancelOrder(Customer customer,String outTradeNo)throws DbException{
        PayOrder payOrder=this.getPayOrder(customer,outTradeNo);
        if(payOrder==null) return null;
        switch (payOrder.getType()){
            case PayOrder.TYPE_TENCENT:
            case PayOrder.TYPE_TENCENT_SCAN:
            case PayOrder.TYPE_TENCENT_APP:
            case PayOrder.TYPE_TENCENT_PULBIC:
                ReverseReqData scanPayQueryReqData=new ReverseReqData("",outTradeNo);
                try{
                    String scanPayQueryResDataStr=WXPay.requestReverseService(scanPayQueryReqData);
                    ReverseResData reverseResData = new ReverseResData();
                    reverseResData=reverseResData.getByXml(scanPayQueryResDataStr);
                    if(reverseResData.getResult_code().equals("SUCCESS") && reverseResData.getReturn_code().equals("SUCCESS")){
                        payOrder.setStatus(PayOrder.STATUS_FAI);
                        if(payOrder.getStatus()==PayOrder.STATUS_FAI)return payOrder;
                        payOrder.setStatus(PayOrder.STATUS_FAI);
                        payOrder.setBody("交易失败" + payOrder.getBody());
                        payOrderDao.update(payOrder);
                    }
                }catch (Exception e){
                    System.out.print(e.toString());
                }
                break;
        }
        return payOrder;
    }

    private  PayOrder getPayOrder(Customer customer,String payNo) throws  DbException{
        Criteria criteria = new Criteria();
        criteria.add(Restrictions.eq("ownerId", customer.getOwnerId()));
        criteria.add(Restrictions.eq("out_trade_no", payNo));
        PagingList<PayOrder> list = payOrderDao.queryEntity(PayOrder.class, criteria);
        if(list!=null && list.size()>0){
            return list.get(0);
        }
        return null;
    }
    private  WithDraw getWithDraw(Customer customer,String payNo) throws  DbException{
        Criteria criteria = new Criteria();
        criteria.add(Restrictions.eq("ownerId", customer.getOwnerId()));
        criteria.add(Restrictions.eq("payNo", payNo));
        PagingList<WithDraw> list = withDrawDao.queryEntity(WithDraw.class,criteria);
        if(list!=null && list.size()>0){
            return list.get(0);
        }
        return null;
    }
}
